"""
Created on 23-Jul-2009

@author: dexen
"""

import os
import sys
import time

import rpyc
from rpyc.utils import server

import dexen
from dexen.system.common import service
from dexen.system.common.base import MyManager
from dexen.system.node.master import comm
from dexen.system.node.master.core import MasterCore
from dexen.system.common.meta import JobMeta
from dexen.system.common.service import DexenAddr

MyManager.register("MasterComm", comm.MasterComm)

#===============================================================================
# Globals
#===============================================================================
        
def start(_master_name, _node_name, _reg_addr, is_local=False):
    global manager, node_name, master_name, reg_addr, svr

    manager = MyManager()
    manager.daemon = True
    manager.start()    
    node_name = _node_name
    master_name = _master_name
    reg_addr = _reg_addr
    assert isinstance(reg_addr, DexenAddr)
    MasterService.ALIASES = [master_name]
    svr = server.ThreadedServer(MasterService, 
                                protocol_config=service.default_config,
                                auto_register=False)
    conn = reg_addr.get_conn()
    my_addr = DexenAddr(service.get_my_ip(is_local), svr.port)
    conn.root.register_master(master_name, my_addr)
    conn.close()
    svr.start()
    manager.shutdown()
    print "Current process id is", os.getpid()
    print "I am exiting the start method in service (master)"


#===============================================================================
# Service
#===============================================================================
class MasterService(dexen.Service):
    def on_connect(self):
        #logging.info("node_manager is connected")
        pass
    
    def on_disconnect(self):
        pass
        
    def schedule(self, slave_name):
        self.comm.assign_slave(slave_name)

    def run_job(self, job_meta):
        job_meta = rpyc.classic.obtain(job_meta)
        assert isinstance(job_meta, JobMeta)
        #self.schema_zip = schema_zip TODO: type buffer --> netref !
        print "master->run_schema(), the type, len", type(job_meta.schema_zip),\
                                                     len(job_meta.schema_zip)  
        self.comm = manager.MasterComm(master_name)
        #self.sp = mp.Process(target=scheduler.run, args=(self.job_meta, self.comm))
        self.core = MasterCore(job_meta, self.comm, reg_addr)
        self.core.start()
        print "Master is running"

    def stop_job(self):
        print "I am stopping the core and comm in the master service"
        self.core.terminate()
        self.core.join()
        print "MasterCore:",self.core.pid, "terminated"
        print "I am exiting the master service process"
        svr.close()

    def get_updates(self):
        return self.comm.get_actions()
    
    def can_schedule(self):
        return self.comm.can_schedule()
